package com.qiyee.dalligent.common.utils;

import java.io.*;
import java.nio.channels.FileChannel;

public class ZeroCopyTest {
    public static void main(String[] args) throws IOException, InterruptedException {
        long start = System.currentTimeMillis();
        File source = new File("D:/dalligent/202202211500.txt");
        File target = new File("D:/dalligent/202202211501.txt");

        //ioCopy(source, target);           // 92MB 483 // 39MB 198 // 8MB 55
        // ioCopyWithBuffer(source, target);// 92MB 154 // 39MB 71 // 8MB 16
        nioCopy(source, target);            // 82MB 82  // 39MB 31 // 8MB 10
        System.out.println(System.currentTimeMillis() - start);
        Thread.sleep(200);
        target.delete();
    }

    public static void ioCopy(File source, File target) throws IOException {
        try (InputStream is = new FileInputStream(source);
             OutputStream os = new FileOutputStream(target)) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = is.read(buffer)) > 0) {
                os.write(buffer, 0, length);
            }
        }
    }

    public static void ioCopyWithBuffer(File source, File target) throws IOException {
        try (InputStream is = new BufferedInputStream(new FileInputStream(source));
             OutputStream os = new BufferedOutputStream(new FileOutputStream(target))) {
            byte[] buffer = new byte[1024];
            int length;
            while ((length = is.read(buffer)) > 0) {
                os.write(buffer, 0, length);
            }
        }
    }

    public static void nioCopy(File source, File target) throws IOException {
        try (FileChannel sourceChannel = new FileInputStream(source).getChannel();
             FileChannel targetChannel = new FileOutputStream(target).getChannel()) {
            for (long count = sourceChannel.size(); count > 0; ) {
                long transferred = sourceChannel.transferTo(sourceChannel.position(), count, targetChannel);
                sourceChannel.position(sourceChannel.position() + transferred);
                count -= transferred;
            }
        }
    }
}

